package jdk7.handlerexception;

import jdk7.handlerexception.exception.FirstException;
import jdk7.handlerexception.exception.SecondException;

/**
 * Description: jdk1.7新特性：用更包容性的类型检查来重新抛出异常（Catch Definite Exception）
 * 捕获指定的异常，在方法的声明上，使用throws语句时，你可以指定更加详细的异常类型。
 * 
 * 个人认为：很有用，编译器变得智能了，而且可以对相应的异常做特定的处理
 * @author Kwum
 * @date 2017年6月26日 下午4:49:48
 * @version 1.0
 */

public class CatchDefiniteExceptionRun {

    public static void main(String args[]){
        try {
            rethrowException("First");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    //这个例子，try块中只能抛出两种异常，但是因为catch里的类型是 Exception，在java SE7以前的版本中，在方法声明中throws 只能写Exception，
    //Java SE7 之前
    public static void rethrowException(String exceptionName) throws Exception {
        try {
            if (exceptionName.equals("First")) {
                throw new FirstException();
            } else {
                throw new SecondException();
            }
        } catch (Exception e) {
            throw e;
        }
    }
    
    //但是在java SE7及以后的版本中，可以在throws后面写 FirstException和SecondException——编译器能判断出throw e语句抛出的异常一定来自try块，
    //并且try块只能抛出FirstException和SecondException。
    //所以尽管catch里的异常类型是Exception，编译器仍然能够知道它是FirstException和 SecondException的实例。
    //但是，如果在catch里对异常重新赋值了，在方法的throws后无法再像下面那样写成FirstException和SecondException了，而需要写成 Exception。
    //具体来说，在Java SE 7及以后版本中，当你在catch语句里声明了一个或多个异常类型，并且在catch块里重新抛出了这些异常，编译器根据下面几个条件来去核实异常的类型： 
    //- Try块里抛出它 
    //- 前面没有catch块处理它 
    //- 它是catch里一个异常类型的父类或子类。
    //Java SE7
    public static void reThrowException(String exceptionName) throws FirstException, SecondException{
        try {
            if ("first".equals(exceptionName)) {
                throw new FirstException();
            } else{
                throw new SecondException();
            }
        }catch (Exception e) {
            throw e;
        }
    }
}